/*
 heat-spectral lib. solves time-dependent PDEs using SEM-NI method.
 Copyright (C) 2009, Altieri Michele and Stefanoni Andrea
 Copyright (C) 2008, Proverbio Alessandro and Radice David

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
    \file map2d.hpp
    \brief This file contains the Map2d class

    The Map2d class contains data and methods for the reppresentation
    and the use of the affine transformation between the reference
    square [-1,1]x[-1,1] into an element and its inverse
*/

# ifndef MAP2D_HPP
# define MAP2D_HPP 1

# include <cassert>

# include "point.hpp"
# include "typedefs.hpp"

namespace spectral {

/**
    \class Map2d
    \brief Affine map from and to the reference square

    The direct map maps the reference element into the given one,
    while the inverse maps an element into the reference square.
*/

/**
    \fn Map2d<T>::Map2d(Point<double> const & A, Point<double> const & B)
    \brief Constructor

    \param A is the bottom-left point of the square we want to map to/from
    \param B is the top-right point of the square we want to map to/from
*/

/**
    \fn Map2d<T>::Map2d(Map2d<T> const & phi)
    \brief Copy constructor
*/

/**
    \fn Map2d<T>::Map2d()
    \brief Default constructor

    This will make an identity map on \f$\hat{\Omega}\f$.
*/

/**
    \fn Point<double> Map2d::operator()(double const & x,double const & y) const
    \brief The overloaded operator '()'

    Computes \f$ \phi(x,h) \f$.
*/

/**
    \fn Map2d<T> & Map2d<T>::operator=(Map2d<T> const & phi)
    \brief Assignment operator

*/


template<mapping T>
class Map2d {
    public:
        Map2d(Point<double> const & A, Point<double> const & B);
        Map2d(Map2d<T> const & phi);
        Map2d();
        Point<double> operator()(double const & x,double const & y) const;
        Map2d<T> & operator=(Map2d<T> const & phi);
    private:
        double _lengthX;      /**< \brief lengthX of the Spectral Element */
        double _lengthY;      /**< \brief lengthY of the Spectral Element */
        double _Ax;           /**< \brief x-coordinate of the bottom left point */
        double _Ay;           /**< \brief y-voordinate of the bottom right point */
};

// ====================================================
// End of proper header
// ====================================================

template<mapping T>
Map2d<T>::Map2d(Point<double> const & A, Point<double> const & B) {
    _Ax=A.get(0);
    _Ay=A.get(1);
    _lengthX=B.get(0)-_Ax;
    _lengthY=B.get(1)-_Ay;
    assert( _lengthX > 0 && _lengthY > 0 );
}

template<mapping T>
Map2d<T>::Map2d(Map2d<T> const & phi) : _lengthX(phi._lengthX),
                                        _lengthY(phi._lengthY),
                                        _Ax(phi._Ax),
                                        _Ay(phi._Ay) {}

template<mapping T>
Map2d<T>::Map2d() : _lengthX(2),
                    _lengthY(2),
                    _Ax(-1),
                    _Ay(-1) {}

template<mapping T>
Map2d<T> & Map2d<T>::operator=(Map2d<T> const & phi) {
    _lengthX=phi._lengthX;
    _lengthY=phi._lengthY;
    _Ax=phi._Ax;
    _Ay=phi._Ay;
    return *this;
}

} // namespace

# endif
